import { app, BrowserWindow, globalShortcut, ipcMain } from "electron";
import { createRequire } from "node:module";
import { fileURLToPath } from "node:url";
import path from "node:path";

const require = createRequire(import.meta.url);
const __dirname = path.dirname(fileURLToPath(import.meta.url));

// The built directory structure
//
// ├─┬─┬ dist
// │ │ └── index.html
// │ │
// │ ├─┬ dist-electron
// │ │ ├── main.js
// │ │ └── preload.mjs
// │
process.env.APP_ROOT = path.join(__dirname, "..");

// 🚧 Use ['ENV_NAME'] avoid vite:define plugin - Vite@2.x
export const VITE_DEV_SERVER_URL = process.env["VITE_DEV_SERVER_URL"];
export const MAIN_DIST = path.join(process.env.APP_ROOT, "dist-electron");
export const RENDERER_DIST = path.join(process.env.APP_ROOT, "dist");

process.env.VITE_PUBLIC = VITE_DEV_SERVER_URL
  ? path.join(process.env.APP_ROOT, "public")
  : RENDERER_DIST;

let win: BrowserWindow | null;

import { PDFDocument, PDFFont, PDFPage } from "pdf-lib";
import { readFileSync, writeFileSync, readdirSync, existsSync } from "node:fs";

import fontkit from "@pdf-lib/fontkit";

const fontPath = "C:\\Windows\\Fonts\\simhei.ttf";
const getFont = () => {
  return readFileSync(fontPath);
};

const sendMsg = (msg: string) => {
  win?.webContents.send("msg-info", msg);
};

const getFiles = async (input: string, town: string, outDir: string) => {
  if (!existsSync(outDir)) {
    sendMsg(`error: ${outDir} 不存在！`);
    return;
  }

  if (!existsSync(fontPath)) {
    sendMsg(`error: 字体文件 ${fontPath} 不存在！`);
    return;
  }

  const names = readdirSync(input).filter((i) => i.includes(town));
  const tbhs = names.map((name) => name.split(town)[1]);
  for (const end of new Set(tbhs)) {
    sendMsg(`开始处理：${end}`);

    const files = names.filter((i) => i.endsWith(end));
    const data = await unionPdf(files, input);
    const pathOut = path.join(outDir, `${town}${end.split(".pdf")[0]}参考图件.pdf`);
    writeFileSync(pathOut, data);
    sendMsg(`处理完成：${end},存储地址为：${pathOut}`);
  }
  sendMsg(`处理结束`);
  console.log("处理结束");
};

const sorts = [
  "影像_执法",
  "现状_执法",
  "永农_执法",
  "影像_耕保",
  "现状_耕保",
  "永农_耕保",
  "影像_林业",
  "现状_林业",
  "永农_林业",
];

const drawText = (page: PDFPage, text: string, customFont: PDFFont) => {
  text = text.replace(".pdf", "");
  page.drawText(text, {
    x: 5,
    y: 6,
    size: 10,
    font: customFont,
  });
};

const unionPdf = async (addPaths: string[], dir: string) => {
  const files: string[] = [];

  sorts.map((i) => {
    const name = addPaths.find((n) => n.startsWith(i));
    if (name != null) files.push(name);
  });

  const pdfdoc1 = await PDFDocument.load(readFileSync(path.join(dir, files[0])));
  pdfdoc1.registerFontkit(fontkit);
  const customFont = await pdfdoc1.embedFont(getFont());

  let count1 = pdfdoc1.getPageCount();
  drawText(pdfdoc1.getPage(0), files[0], customFont);

  for (let i = 1; i < files.length; i++) {
    const pdfdoc2 = await PDFDocument.load(readFileSync(path.join(dir, files[i])));
    for (let j = 0; j < pdfdoc2.getPageCount(); j++) {
      const [existingPage] = await pdfdoc1.copyPages(pdfdoc2, [j]);
      drawText(existingPage, files[i], customFont);
      pdfdoc1.insertPage(count1, existingPage);
      count1++;
    }
  }

  const base64 = await pdfdoc1.save();
  return base64;
};

function createWindow() {
  win = new BrowserWindow({
    icon: path.join(process.env.VITE_PUBLIC, "pdf.png"),
    webPreferences: {
      preload: path.join(__dirname, "preload.mjs"),
    },
    autoHideMenuBar: true,
  });

  if (VITE_DEV_SERVER_URL) {
    win.loadURL(VITE_DEV_SERVER_URL);
  } else {
    // win.loadFile('dist/index.html')
    win.loadFile(path.join(RENDERER_DIST, "index.html"));
  }
  globalShortcut.register("ctrl+F12", () => win!.webContents.openDevTools());

  ipcMain.handle("pdf-union", (evt, { inputdir, outdir, town }) => {
    getFiles(inputdir, town, outdir);
  });
}

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on("window-all-closed", () => {
  if (process.platform !== "darwin") {
    app.quit();
    win = null;
  }
});

app.on("activate", () => {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow();
  }
});

app.whenReady().then(createWindow);
